package com.cbs.android.component.log;

import android.util.Log;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by brochexu on 10/30/14.
 */
public final class L {
    private static final String SPLITER = "------------------------------";
    public static final int NONE = 0;
    public static final int ERROR = 1;
    public static final int WARN = 2;
    public static final int INFO = 3;
    public static final int DEBUG = 4;
    public static final int VERBOS = 5;

    private static int LOG_LEVEL = DEBUG;

    private static List<LogHandler> handlers;

    private L() {
    }

    public static int getLogLevel() {
        return LOG_LEVEL;
    }

    public static void setLogLevel(int logLevel) {
        if (logLevel > VERBOS) {
            logLevel = VERBOS;
        } else if (logLevel < NONE) {
            logLevel = NONE;
        }
        LOG_LEVEL = logLevel;
    }

    public static void addHandler(LogHandler handler) {
        if (handlers == null) {
            handlers = new ArrayList<>();
        }
        handlers.add(handler);
    }

    public static void removeHandler(LogHandler handler) {
        if (handlers != null) {
            handlers.remove(handler);
        }
    }

    public static void e(String tag, String message) {
        handleLog(ERROR, tag, message, null);
        if (LOG_LEVEL >= ERROR) {
            Log.e(tag, validateMessage(message));
        }
    }

    public static void w(String tag, String message) {
        handleLog(WARN, tag, message, null);
        if (LOG_LEVEL >= WARN) {
            Log.w(tag, validateMessage(message));
        }
    }

    public static void i(String tag, String message) {
        handleLog(INFO, tag, message, null);
        if (LOG_LEVEL >= INFO) {
            Log.i(tag, validateMessage(message));
        }
    }

    public static void d(String tag, String message) {
        handleLog(DEBUG, tag, message, null);
        if (LOG_LEVEL >= DEBUG) {
            Log.d(tag, validateMessage(message));
        }
    }

    public static void v(String tag, String message) {
        handleLog(VERBOS, tag, message, null);
        if (LOG_LEVEL >= VERBOS) {
            Log.v(tag, validateMessage(message));
        }
    }

    public static void e(String tag, String message, Throwable throwable) {
        handleLog(ERROR, tag, message, throwable);
        if (LOG_LEVEL >= ERROR) {
            Log.e(tag, validateMessage(message) + "\n" + getThrowableString(throwable));
        }
    }

    public static void w(String tag, String message, Throwable throwable) {
        handleLog(WARN, tag, message, throwable);
        if (LOG_LEVEL >= WARN) {
            Log.w(tag, validateMessage(message) + "\n" + getThrowableString(throwable));
        }
    }

    public static void i(String tag, String message, Throwable throwable) {
        handleLog(INFO, tag, message, throwable);
        if (LOG_LEVEL >= INFO) {
            Log.i(tag, validateMessage(message) + "\n" + getThrowableString(throwable));
        }
    }

    public static void d(String tag, String message, Throwable throwable) {
        handleLog(DEBUG, tag, message, throwable);
        if (LOG_LEVEL >= DEBUG) {
            Log.d(tag, validateMessage(message) + "\n" + getThrowableString(throwable));
        }
    }

    public static void v(String tag, String message, Throwable throwable) {
        handleLog(VERBOS, tag, message, throwable);
        if (LOG_LEVEL >= VERBOS) {
            Log.v(tag, validateMessage(message) + "\n" + getThrowableString(throwable));
        }
    }

    public static void es(String tag) {
        e(tag, SPLITER);
    }

    public static void ws(String tag) {
        w(tag, SPLITER);
    }

    public static void is(String tag) {
        i(tag, SPLITER);
    }

    public static void ds(String tag) {
        d(tag, SPLITER);
    }

    public static void vs(String tag) {
        v(tag, SPLITER);
    }

    private static void handleLog(int level, String tag, String message, Throwable throwable) {
        if (handlers != null) {
            for (LogHandler handler : handlers) {
                handler.handle(level, tag, message, throwable);
            }
        }
    }

    private static String validateMessage(String message) {
        if (message == null) {
            message = "(null message)";
        } else if (message.equals("")) {
            message = "(empty message)";
        }
        return message;
    }

    private static String getThrowableString(Throwable throwable) {
        StringBuilder stringBuilder = new StringBuilder();
        for (StackTraceElement element : throwable.getStackTrace()) {
            stringBuilder.append(element.toString());
            stringBuilder.append("\n");
        }
        return stringBuilder.toString();
    }
}
